home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP06.ZIP / CHAP06 / EDATAOBJ / IDATAOBJ.CPP < prev    next >
C/C++ Source or Header  |  1993-04-21  |  12KB  |  477 lines

  1. /*
  2.  * IDATAOBJ.CPP
  3.  * Data Object for Chapter 6
  4.  *
  5.  * Implementation of the IDataObject interface for CDataObject.
  6.  *
  7.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Software Design Engineer
  10.  * Microsoft Systems Developer Relations
  11.  *
  12.  * Internet  :  kraigb@microsoft.com
  13.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  14.  */
  15.  
  16.  
  17. #include "dataobj.h"
  18.  
  19.  
  20.  
  21. /*
  22.  * CImpIDataObject::CImpIDataObject
  23.  * CImpIDataObject::~CImpIDataObject
  24.  *
  25.  * Parameters (Constructor):
  26.  *  pObj            LPVOID of the object we're in.
  27.  *  punkOuter       LPUNKNOWN to which we delegate.
  28.  */
  29.  
  30. CImpIDataObject::CImpIDataObject(LPVOID pObj, LPUNKNOWN punkOuter)
  31.     {
  32.     m_cRef=0;
  33.     m_pObj=pObj;
  34.     m_punkOuter=punkOuter;
  35.     return;
  36.     }
  37.  
  38. CImpIDataObject::~CImpIDataObject(void)
  39.     {
  40.     return;
  41.     }
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48. /*
  49.  * CImpIDataObject::QueryInterface
  50.  * CImpIDataObject::AddRef
  51.  * CImpIDataObject::Release
  52.  *
  53.  * Purpose:
  54.  *  IUnknown members for CImpIDataObject object.
  55.  */
  56.  
  57. STDMETHODIMP CImpIDataObject::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  58.     {
  59.     return m_punkOuter->QueryInterface(riid, ppv);
  60.     }
  61.  
  62.  
  63. STDMETHODIMP_(ULONG) CImpIDataObject::AddRef(void)
  64.     {
  65.     ++m_cRef;
  66.     return m_punkOuter->AddRef();
  67.     }
  68.  
  69. STDMETHODIMP_(ULONG) CImpIDataObject::Release(void)
  70.     {
  71.     --m_cRef;
  72.     return m_punkOuter->Release();
  73.     }
  74.  
  75.  
  76.  
  77.  
  78.  
  79. /*
  80.  * CImpIDataObject::GetData
  81.  *
  82.  * Purpose:
  83.  *  Retrieves data described by a specific FormatEtc into a StgMedium
  84.  *  allocated by this function.  Used like GetClipboardData.
  85.  *
  86.  * Parameters:
  87.  *  pFE             LPFORMATETC describing the desired data.
  88.  *  pSTM            LPSTGMEDIUM in which to return the data.
  89.  *
  90.  * Return Value:
  91.  *  HRESULT         NOERROR on success, error code otherwise.
  92.  */
  93.  
  94. STDMETHODIMP CImpIDataObject::GetData(LPFORMATETC pFE, LPSTGMEDIUM pSTM)
  95.     {
  96.     LPCDataObject   pObj=(LPCDataObject)m_pObj;
  97.     UINT            cf=pFE->cfFormat;
  98.  
  99.     /*
  100.      * This function is just cycling through each format you support
  101.      * and finding a match with the requested one, rendering that
  102.      * data, then returning NOERROR, otherwise returning either
  103.      * DATA_E_FORMATETC or STG_E_MEDIUMFULL on error.
  104.      */
  105.  
  106.     //Check the aspects we support.
  107.     if (!(DVASPECT_CONTENT & pFE->dwAspect))
  108.         return ResultFromScode(DATA_E_FORMATETC);
  109.  
  110.     switch (cf)
  111.         {
  112.         case CF_METAFILEPICT:
  113.             if (!(TYMED_MFPICT & pFE->tymed))
  114.                 break;
  115.  
  116.             return pObj->RenderMetafilePict(pSTM);
  117.  
  118.         case CF_BITMAP:
  119.             if (!(TYMED_GDI & pFE->tymed))
  120.                 break;
  121.  
  122.             return pObj->RenderBitmap(pSTM);
  123.  
  124.         case CF_TEXT:
  125.             if (!(TYMED_HGLOBAL & pFE->tymed))
  126.                 break;
  127.  
  128.             return pObj->RenderText(pSTM);
  129.  
  130.         default:
  131.             break;
  132.         }
  133.  
  134.     return ResultFromScode(DATA_E_FORMATETC);
  135.     }
  136.  
  137.  
  138.  
  139.  
  140. /*
  141.  * CImpIDataObject::GetDataHere
  142.  *
  143.  * Purpose:
  144.  *  Renders the specific FormatEtc into caller-allocated medium
  145.  *  provided in pSTM.
  146.  *
  147.  * Parameters:
  148.  *  pFE             LPFORMATETC describing the desired data.
  149.  *  pSTM            LPSTGMEDIUM providing the medium into which
  150.  *                  wer render the data.
  151.  *
  152.  * Return Value:
  153.  *  HRESULT         NOERROR on success, error code otherwise.
  154.  */
  155.  
  156. STDMETHODIMP CImpIDataObject::GetDataHere(LPFORMATETC pFE, LPSTGMEDIUM pSTM)
  157.     {
  158.     //We don't implement this now.
  159.     return ResultFromScode(E_NOTIMPL);
  160.     }
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167. /*
  168.  * CImpIDataObject::QueryGetData
  169.  *
  170.  * Purpose:
  171.  *  Tests if a call to ::GetData with this FormatEtc will provide
  172.  *  any rendering; used like IsClipboardFormatAvailable.
  173.  *
  174.  * Parameters:
  175.  *  pFE             LPFORMATETC describing the desired data.
  176.  *
  177.  * Return Value:
  178.  *  HRESULT         NOERROR on success, error code otherwise.
  179.  */
  180.  
  181. STDMETHODIMP CImpIDataObject::QueryGetData(LPFORMATETC pFE)
  182.     {
  183.     LPCDataObject   pObj=(LPCDataObject)m_pObj;
  184.     UINT            cf=pFE->cfFormat;
  185.     BOOL            fRet=FALSE;
  186.  
  187.     /*
  188.      * This function is just cycling through each format you support
  189.      * and finding a match with the requested one, returning NOERROR
  190.      * if you do have it, S_FALSE if you don't.
  191.      */
  192.  
  193.     //Check the aspects we support.
  194.     if (!(DVASPECT_CONTENT & pFE->dwAspect))
  195.         return ResultFromScode(S_FALSE);
  196.  
  197.     switch (cf)
  198.         {
  199.         case CF_METAFILEPICT:
  200.             fRet=(BOOL)(pFE->tymed & TYMED_MFPICT);
  201.             break;
  202.  
  203.         case CF_BITMAP:
  204.             fRet=(BOOL)(pFE->tymed & TYMED_GDI);
  205.             break;
  206.  
  207.         case CF_TEXT:
  208.             fRet=(BOOL)(pFE->tymed & TYMED_HGLOBAL);
  209.             break;
  210.  
  211.         default:
  212.             fRet=FALSE;
  213.             break;
  214.         }
  215.  
  216.     return fRet ? NOERROR : ResultFromScode(S_FALSE);
  217.     }
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224. /*
  225.  * CImpIDataObject::GetCanonicalFormatEtc
  226.  *
  227.  * Purpose:
  228.  *  Provides the caller with an equivalent FormatEtc to the one
  229.  *  provided when different FormatEtcs will produce exactly the
  230.  *  same renderings.
  231.  *
  232.  * Parameters:
  233.  *  pFEIn            LPFORMATETC of the first description.
  234.  *  pFEOut           LPFORMATETC of the equal description.
  235.  *
  236.  * Return Value:
  237.  *  HRESULT         NOERROR on success, error code otherwise.
  238.  */
  239.  
  240. STDMETHODIMP CImpIDataObject::GetCanonicalFormatEtc(LPFORMATETC pFEIn
  241.     , LPFORMATETC pFEOut)
  242.     {
  243.     /*
  244.      *  1.  If you support an equivalent of pFEIn, return it in pFEOut.
  245.      *  2.  Return NOERROR if you filled pFEOut with anything, otherwise
  246.      *      return DATA_S_SAMEFORMATETC.  If you say that all renderings
  247.      *      are identical, return DATA_S_SAMEFORMATETC.
  248.      */
  249.  
  250.     return ResultFromScode(DATA_S_SAMEFORMATETC);
  251.     }
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258. /*
  259.  * CImpIDataObject::SetData
  260.  *
  261.  * Purpose:
  262.  *  Places data described by a FormatEtc and living in a StgMedium
  263.  *  into the object.  The object may be responsible to clean up the
  264.  *  StgMedium before exiting.
  265.  *
  266.  * Parameters:
  267.  *  pFE             LPFORMATETC describing the data to set.
  268.  *  pSTM            LPSTGMEDIUM containing the data.
  269.  *  fRelease        BOOL indicating if this function is responsible for
  270.  *                  freeing the data.
  271.  *
  272.  * Return Value:
  273.  *  HRESULT         NOERROR on success, error code otherwise.
  274.  */
  275.  
  276. STDMETHODIMP CImpIDataObject::SetData(LPFORMATETC pFE, STGMEDIUM FAR *pSTM
  277.     , BOOL fRelease)
  278.     {
  279.     //We don't handle SetDatas here.
  280.     return ResultFromScode(DATA_E_FORMATETC);
  281.     }
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288. /*
  289.  * CImpIDataObject::EnumFormatEtc
  290.  *
  291.  * Purpose:
  292.  *  Returns an IEnumFORMATETC object through which the caller can iterate
  293.  *  to learn about all the data formats this object can provide through
  294.  *  either ::GetData[Here] or ::SetData.
  295.  *
  296.  * Parameters:
  297.  *  dwDir           DWORD describing a data direction, either DATADIR_SET
  298.  *                  or DATADIR_GET.
  299.  *  ppEnum          LPENUMFORMATETC FAR * in which to return the pointer
  300.  *                  to the enumerator.
  301.  *
  302.  * Return Value:
  303.  *  HRESULT         NOERROR on success, error code otherwise.
  304.  */
  305.  
  306. STDMETHODIMP CImpIDataObject::EnumFormatEtc(DWORD dwDir
  307.     , LPENUMFORMATETC FAR *ppEnum)
  308.     {
  309.     LPCDataObject   pObj=(LPCDataObject)m_pObj;
  310.  
  311.     /*
  312.      * We only support ::GetData in this object so we return NULL for
  313.      * DATADIR_SET.  Otherwise we instantiate one of our CEnumFormatEtc
  314.      * objects which has all the appropriate functions; we only need to
  315.      * tell it where our arrays live.
  316.      *
  317.      * The m_punkOuter passed to the enumerator allows the enumerator
  318.      * to AddRef and Release our controlling unknown as it receives
  319.      * reference counting calls.  By calling AddRef itself, it can
  320.      * insure that the object that holds the data context will stick
  321.      * around as long as the enumerator itself is around.  Otherwise
  322.      * it could be enumerating through bogus data.
  323.      */
  324.  
  325.     switch (dwDir)
  326.         {
  327.         case DATADIR_GET:
  328.             *ppEnum=(LPENUMFORMATETC)new CE